#ifndef Z_FIELD_H_
#define Z_FIELD_H_

#include <stdio.h>
#include <stdlib.h>

#ifdef _MSC_VER
#define __snprintf(a, b, c, d) _snprintf(a, b, c, b, d)
#else
#define __snprintf(a, b, c, d) snprintf(a, b, c, b, d)
#endif

template <typename T>
struct ZFixedLengthField {
    enum {Length = T::Length};
    char    zStr[Length+1];
    typename T::FieldType   zVal;
	ZFixedLengthField() {
		memset(zStr, ' ', Length);
		zStr[Length] = '\0';
		zVal = T::def();
	}
    bool get(const char **data, int *len) {
        if ( *len < Length ) return false;
        memcpy(zStr, *data, Length);
        zStr[Length] = '\0';
		int pos = Length - 1;
		while(pos >= 0 && zStr[pos] == ' ')
			zStr[pos--] = '\0';

        if ( !T::value(zStr, &zVal) ) return false;
        *data += Length;
        *len -= Length;
        return true;
    }
    void set(char **data, int *len) {
        T::set(*data, zVal);
        *data += Length;
        *len += Length;
    }
};

template <int N>
struct ZIntField {
    enum {Length = N};
    typedef int FieldType;
	static int def() {return 0;}
    static bool value(char *data, FieldType *v) {
        *v = atoi(data);
        return true;
    }
    static void set(char *data, FieldType v) {
        __snprintf(data, N, "%-*d", v);
    }
};

template <int N>
struct ZLongField {
    enum {Length = N};
    typedef long long FieldType;
	static long long def() {return 0;}
    static bool value(char *data, FieldType *v) {
        *v = atol(data);
        return true;
    }
    static void set(char *data, FieldType v) {
        __snprintf(data, N, "%-*lld", v);
    }
};

template <int N>
struct ZDblField {
    enum {Length = N};
    typedef double FieldType;
	static double def() {return 0.0;}
    static bool value(char *data, FieldType *v) {
        *v = atof(data);
        return true;
    }
    static void set(char *data, FieldType v) {
        __snprintf(data, N, "%-*f", v);
    }
};

template <int N>
struct ZCharField {
    enum {Length = N};
    typedef char FieldType;
	static char def() {return ' ';}
    static bool value(char *data, FieldType *v) {
        *v = *data;
        return true;
    }
    static void set(char *data, FieldType v) {
        __snprintf(data, N, "%-*c", v);
    }
};

template <int N>
struct ZStrField {
    enum {Length = N};
    typedef const char* FieldType;
	static const char* def() {return 0;}
    static bool value(char *data, FieldType *v) {
        *v = data;
        return true;
    }
    static void set(char *data, FieldType v) {
        __snprintf(data, N, "%-*s", v ? v : " ");
    }
};

#endif // Z_FIELD_H_
